import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { ClientDto } from 'src/app/models/sys/client.dto';
import { ApiService } from 'src/app/services/api.service';
import { EditMode } from 'src/app/models/enums/edit-mode.enum';
import { NzMessageService } from 'ng-zorro-antd/message';
import { Consts } from 'src/app/consts/consts';
import { AddClientParam } from 'src/app/models/param/add-client.param';
import { UpdateClientParam } from 'src/app/models/param/update-client.param';
import { BehaviorSubject } from 'rxjs';

const CLIENT_ID = 'clientId';
const CLIENT_NAME = 'clientName';
const CLIENT_SECRET = 'clientSecret';
@Component({
  selector: 'app-add-client',
  templateUrl: './add-client.component.html',
  styleUrl: './add-client.component.less'
})
export class AddClientComponent implements OnInit {
  @Input() modeSubject!: BehaviorSubject<{ mode: EditMode, client?: ClientDto }>;
  @Output() addClientEvent = new EventEmitter<boolean>();

  editMode: EditMode = EditMode.ADD;
  modeEnum = EditMode;

  // Edit modal
  client?: ClientDto;
  addForm!: UntypedFormGroup;
  listOfUris: Array<{ id: number; controlInstance: string; value: string }> = [];
  listOfScopes: Array<{ id: number; controlInstance: string; value: string }> = [];
  submitted = false;

  constructor(private _api: ApiService,
    private _fb: UntypedFormBuilder,
    private _messageService: NzMessageService) { }

  ngOnInit(): void {
    this.createAddForm();
  }

  get fm() {
    return this.addForm.controls;
  }

  createAddForm() {
    this.addForm = this._fb.group({});
    this.addForm.addControl(CLIENT_ID, new UntypedFormControl('', [Validators.minLength(2), Validators.maxLength(20)]));
    this.addForm.addControl(CLIENT_SECRET, new UntypedFormControl('', [Validators.minLength(6), Validators.maxLength(20)]));
    this.addForm.addControl(CLIENT_NAME, new UntypedFormControl('', [Validators.minLength(2), Validators.maxLength(20)]));

    this.modeSubject.subscribe((value) => {
      this.editMode = value.mode;
      if (this.editMode == EditMode.ADD) {
        console.log('add mode');
        this.addForm.get(CLIENT_ID)?.addValidators(Validators.required);
        this.addForm.get(CLIENT_SECRET)?.addValidators(Validators.required);
        this.addForm.get(CLIENT_NAME)?.addValidators(Validators.required);
      } else {
        console.log('edit mode');
        this.client = value.client!;
        this.initParam(this.client);
      }
    })

    this.initListOfUris();
    this.initListOfScopes();
  }

  // 若是编辑，则预设控件的值
  initParam(client: ClientDto) {
    console.log('set edit form');
    this.client = client;
    this.addForm.get(CLIENT_ID)?.setValue(client.clientId);
    this.addForm.get(CLIENT_NAME)?.setValue(client.clientName);
    this.listOfUris = [];
    client.redirectUris.forEach((value, index) => {
      const urlControl: { id: number; controlInstance: string; value: string }
        = { id: index, controlInstance: `uri${index}`, value: value };

      console.log(`new urlControl ${urlControl.id} ${urlControl.controlInstance} ${urlControl.value}`);
      this.listOfUris.push(urlControl);
      this.addForm.addControl(urlControl.controlInstance,
        this._fb.control('', [Validators.required])
      );
    });

    client.scopes.forEach((value, index) => {
      const scopeControl: { id: number; controlInstance: string; value: string }
        = { id: index, controlInstance: `scope${index}`, value: value };
      this.listOfScopes.push(scopeControl);
      this.addForm.addControl(scopeControl.controlInstance,
        this._fb.control('', [Validators.required, Validators.minLength(2), Validators.maxLength(20)]));
    });
  }

  initListOfUris() {
    const uriId = this.listOfUris.length > 0 ? this.listOfUris[this.listOfUris.length - 1].id + 1 : 0;
    const uriControl = {
      id: uriId,
      controlInstance: `http://${uriId}`,
      value: ''
    };
    const urlIndex = this.listOfUris.push(uriControl);
    this.addForm.addControl(
      this.listOfUris[urlIndex - 1].controlInstance,
      this._fb.control('')
    );

    for (const uri of this.listOfUris) {
      const controlName = uri.controlInstance;
      this.addForm.get(controlName)?.setValue(uri.value);
    }
  }

  // 初始化scopes列表，若是编辑，则listOfScopes在之前已经设定
  initListOfScopes() {
    const scopeId = this.listOfScopes.length > 0 ? this.listOfScopes[this.listOfScopes.length - 1].id + 1 : 0;
    const scopeControl = {
      id: scopeId,
      controlInstance: '',
      value: ''
    }
    const scopeIndex = this.listOfScopes.push(scopeControl);
    this.addForm.addControl(
      this.listOfScopes[scopeIndex - 1].controlInstance,
      this._fb.control('')
    );

    for (const scope of this.listOfScopes) {
      const controlName = scope.controlInstance;
      this.addForm.get(controlName)?.setValue(scope.value);
    }
  }


  // 增加一个URI控件，控件名称编号与索引相关
  addUriField(e?: MouseEvent): void {
    e?.preventDefault();

    const id = this.listOfUris.length > 0 ? this.listOfUris[this.listOfUris.length - 1].id + 1 : 0;
    const control = {
      id,
      controlInstance: `uri${id}`,
      value: ''
    };
    const index = this.listOfUris.push(control);
    console.log(this.listOfUris[this.listOfUris.length - 1]);
    this.addForm.addControl(
      this.listOfUris[index - 1].controlInstance,
      this._fb.control('', Validators.required)
    );
  }

  // 移除一个URI控件，控件名称编号与索引相关
  removeUriField(i: { id: number; controlInstance: string, value: string }, e: UIEvent) {
    e.preventDefault();

    if (this.listOfUris.length > 0) {
      const index = this.listOfUris.indexOf(i);
      this.listOfUris.splice(index, 1);
      console.log(this.listOfUris);
      this.addForm.removeControl(i.controlInstance);
    }
  }

  // 增加一个权限控件，控件名称编号与索引相关
  addScopeField(e?: MouseEvent): void {
    e?.preventDefault();

    const id = this.listOfScopes.length > 0 ? this.listOfScopes[this.listOfScopes.length - 1].id + 1 : 0;
    const control = {
      id,
      controlInstance: `scope${id}`,
      value: ''
    };
    const index = this.listOfScopes.push(control);
    console.log(this.listOfScopes[this.listOfScopes.length - 1]);
    this.addForm.addControl(
      this.listOfScopes[index - 1].controlInstance,
      this._fb.control('', Validators.required)
    );
  }

  // 增移除一个权限控件，控件名称编号与索引相关
  removeScopeField(i: { id: number; controlInstance: string, value: string }, e: UIEvent) {
    e.preventDefault();

    if (this.listOfScopes.length > 0) {
      const index = this.listOfScopes.indexOf(i);
      this.listOfScopes.splice(index, 1);
      console.log(this.listOfScopes);
      this.addForm.removeControl(i.controlInstance);
    }
  }

  // 新建操作
  handleCreate() {
    this.submitted = true;
    if (!this.addForm.valid) {
      this._messageService.warning("输入有错误!");
      return;
    }

    const param = new AddClientParam();
    param.clientId = this.addForm.get('clientId')?.value;
    param.clientSecret = this.addForm.get('clientSecret')?.value;
    param.clientName = this.addForm.get('clientName')?.value;

    // redirect uri 的控件保存在listOfUris
    param.redirectUris = this.getUris();

    // scope uri 的控件保存在listOfScopes
    param.scopes = this.getScopes();

    console.log(`${JSON.stringify(param)}`);
    this._api.addClient(param).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK) {
        this._messageService.info("创建客户端成功!");
        this.resetModal();
        this.addClientEvent.emit(true);
      } else {
        this._messageService.warning("创建客户端失败:" + resp.message);
      }
    });
  }

  // 编辑操作
  handleUpdate() {
    this.submitted = true;
    if (!this.addForm.valid) {
      this._messageService.warning('参数错误!');
      return;
    }

    const param = new UpdateClientParam();
    param.clientId = this.addForm.get('clientId')?.value;
    param.clientSecret = this.addForm.get('clientSecret')?.dirty ? this.addForm.get('clientSecret')?.value : undefined;
    param.clientName = this.addForm.get('clientName')?.dirty ? this.addForm.get('clientName')?.value : undefined;
    param.redirectUris = this.getUris();
    param.scopes = this.getScopes();

    console.log(`update client: ${JSON.stringify(param)}`);
    this._api.updateClient(param).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK) {
        this._messageService.info("更新客户端成功!");
        this.resetModal();
        this.addClientEvent.emit(true);
      } else {
        this._messageService.warning("更新客户端失败!" + resp.message);
      }
    });
  }

  private getUris(): string[] | undefined {
    if (this.listOfUris.length > 0) {
      const uris = [];
      for (const uriItem of this.listOfUris) {
        const uri = this.addForm.get(uriItem.controlInstance)?.value;
        if (uri != null && uri.length > 0) {
          uris.push(uri);
        }
      }
      return uris;
    }

    return undefined;
  }

  private getScopes(): string[] | undefined {
    if (this.listOfScopes.length > 0) {
      const scopes = [];
      for (const scopeItem of this.listOfScopes) {
        const scope = this.addForm.get(scopeItem.controlInstance)?.value;
        if (scope != null && scope.length > 0) {
          scopes.push(scope);
        }
      }
      return scopes;
    }

    return undefined;
  }

  // 编辑或新建的按钮统一入口
  submitAddForm(): void {
    if (this.editMode === EditMode.ADD) {
      this.handleCreate();
    } else {
      this.handleUpdate();
    }
  }

  // 对话框取消
  handleCancel(event: UIEvent): void {
    event.preventDefault();
    this.resetModal();
    this.addClientEvent.emit(false);
  }

  resetModal() {
    this.client = undefined;
    this.listOfUris = [];
    this.listOfScopes = [];
    this.submitted = false;
    this.editMode = EditMode.ADD;
  }
}
